using System;
using System.IO;
using System.Collections.Generic;
using System.Text;

using Walkmen.Util;

namespace Walkmen.OpenMG
{
    public enum CodecType: byte
    {
        ATRAC3  = 0x00,
        ATRAC3P = 0x01,
        MP3     = 0x03,
        LPCM    = 0x04,
        WMA     = 0x05
    }

    class OpenMGHeader
    {
        private const int EA3_HEADER_SIZE = 96;

        private string _fileType;
        private short _version;
        private int _size;
        private short _eid;
        private CodecType _codecType;

        public CodecType CodecType
        {
            get { return _codecType; }
            set { _codecType = value; }
        }

        public string FileType
        {
            get { return _fileType; }
            set { _fileType = value; }
        }

        public short Version
        {
            get { return _version; }
            set { _version = value; }
        }

        public int Size
        {
            get { return _size; }
            set { _size = value; }
        }

        public short Eid
        {
            get { return _eid; }
            set { _eid = value; }
        }

        public static OpenMGHeader Parse(Stream stream)
        {
            OpenMGHeader header = new OpenMGHeader();

            byte[] fileType = new byte[3];
            int r = stream.Read(fileType, 0, fileType.Length);
            if (r != fileType.Length)
            {
                throw new FormatException();
            }
            header.FileType = Encoding.ASCII.GetString(fileType);
            // +3

            byte[] version = new byte[2];
            r = stream.Read(version, 0, version.Length);
            if (r != version.Length)
            {
                throw new FormatException();
            }
            header.Version = NumericUtils.ReadShort(version, 0);
            // +5

            header.Size = stream.ReadByte();
            if (header.Size != EA3_HEADER_SIZE)
            {
                throw new FormatException();
            }
            // +6

            byte[] eid = new byte[2];
            r = stream.Read(eid, 0, eid.Length);
            if (r != eid.Length)
            {
                throw new FormatException();
            }
            header.Eid = NumericUtils.ReadShort(eid, 0);
            if (header.Eid != -1 && header.Eid != -128)
            {
                throw new FormatException("Encrypted file! Eid:" + header.Eid);
            }
            // +8

            stream.Seek(24, SeekOrigin.Current);
            // +32

            byte codecType = (byte)stream.ReadByte();
            header.CodecType = (CodecType)codecType;
            // +33

            stream.Seek(63, SeekOrigin.Current);
            // +96

            return header;
        }
    }
}
